Kompozit adat típusok - ORACLE

Az egyszerű adattípusokkal szemben jóval hatékonyabban tudjuk használni a kompozit adattípusokat. Egyfelől gyorsabb az elérésük, mert a memóriában tárolódnak (pontosabban a Program Global Area-ban, de ez most nem fontos kérdés). Két fő típusa van:

Records: egy sornyi adatot tartalmaz változó értékekkel. Akkor használjuk, ha egymással összefüggő adatokat szeretnénk tárolni (mint pl. a HR sémában egy Employee adatai). Leginkább akkor látom hasznát, ha collection-nel együtt használjuk. Létrehozása két féle módon történhet:

Ha egy adatbázis tábla struktúrájára hivatkozunk:

DECLARE

r_tel phone_numbs%rowtype;

BEGIN

SELECT * INTO r_tel FROM phone_numbs WHERE id = '1';

END;
Vagy a változókat egyenként adjuk hozzá:
DECLARE

t_tel is record (phone_home varchar2(10), phone_mobile phone_numbs.phone_mobile%type);

r_tel t_tel;

BEGIN

SELECT phone_home, phone_mobile INTO r_tel FROM phone_numbs WHERE id = '1';

END;


Collections: több sornyi adatot tartalmaz ugyanolyan adattípussal. Ezt három féle módon tudja tárolni: mint Varray, ez esetben a benne tárolt változók index értéke 1-től nő, de meg kell határozni már létrehozásakor, hogy hány eleme lesz (ezt sok esetben nem tudjuk, ezért én nem is szoktam használni). Lehet továbbá Nested table, amelynek index értéke hasonlóan az előzőhöz 1-től nő, de nem kell meghatározni az elemszámot a létrehozásakor, azaz új érték hozzáadásakor index értéke automatikusan megnő, továbbá törölhetünk is belőle elemeket. A harmadik típus az Associative array, más néven Index by array, amelynél az index értéke bármi lehet, mi határozhatjuk meg. Ha jelentése van számunkra az Index értékének, akkor érdemes használni (pl. az index értéke lehet mondjuk 'Alma').

Nested table létrehozására példa:
DECLARE

TYPE e_tel IS TABLE OF VARCHAR2(100);

tels e_tel := e_tel();

idx pls_integer := 1;

BEGIN

FOR x IN 1..10 LOOP

tels.extend;

SELECT phone_mobile INTO tels(idx) FROM phone_numbs WHERE id = x;

idx := idx + 1;

END LOOP;

END;


Associative array létrehozására példa:
DECLARE

TYPE e_tel IS TABLE OF phone_numbs.phone_mobile%TYPE INDEX BY PLS_INTEGER;

tels e_tel;

BEGIN

FOR x IN 1..10 LOOP

SELECT phone_mobile INTO tels(idx) FROM phone_numbs WHERE id = x;

END LOOP;

END;


In Memory Table: érdemes ezt a két fő típust vegyíteni egymással, azaz collection-höz record-ot hozzáadni. Ezzel igen hatékonyan és gyorsan tudunk táblákból lekérdezéseket végezni, üzleti folyamatokat leképezni. Az alábbi példában egy táblából lekérdezzük egy tábla elemeit, azt módosítjuk, majd egy másik táblába beírjuk az új értékeket:
DECLARE

TYPE e_type IS RECORD (data_first VARCHAR2(20), data_second VARCHAR2(20));

TYPE e_list IS TABLE OF e_type INDEX BY BINARY_INTEGER;

t_list e_list;

BEGIN

sql_statement := 'SELECT a.data_first, a.data_second FROM data_table';

EXECUTE IMMEDIATE sql_statement BULK COLLECT INTO t_list;

END;


Collection esetében viszont meg kell említeni, hogy nagy méretű adatmennyiség esetén van rá esély, hogy nem fog működni, mivel a memória megtelik. Ebben az esetben érdemes lehet a cursor használata, amely nem tölti be az összes rekordot a memóriába, hanem soronként történik a memóriába írás.